home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 4: GNU Archives / Linux Cubed Series 4 - GNU Archives.iso / gnu / inetutil.1 / inetutil / inetutils-1.1 / ftp / ruserpass.c < prev   
Encoding:
C/C++ Source or Header  |  1996-07-13  |  7.2 KB  |  288 lines

  1. /*
  2.  * Copyright (c) 1985, 1993, 1994
  3.  *    The Regents of the University of California.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #ifndef lint
  35. static char sccsid[] = "@(#)ruserpass.c    8.4 (Berkeley) 4/27/95";
  36. #endif /* not lint */
  37.  
  38. #include <sys/types.h>
  39. #include <sys/stat.h>
  40.  
  41. #include <ctype.h>
  42. #include <err.h>
  43. #include <errno.h>
  44. #include <stdio.h>
  45. #include <stdlib.h>
  46. #include <string.h>
  47. #include <unistd.h>
  48.  
  49. #include "ftp_var.h"
  50.  
  51. static    int token __P((void));
  52. static    FILE *cfile;
  53.  
  54. #define    DEFAULT    1
  55. #define    LOGIN    2
  56. #define    PASSWD    3
  57. #define    ACCOUNT 4
  58. #define MACDEF  5
  59. #define    ID    10
  60. #define    MACH    11
  61.  
  62. static char tokval[100];
  63.  
  64. static struct toktab {
  65.     char *tokstr;
  66.     int tval;
  67. } toktab[]= {
  68.     { "default",    DEFAULT },
  69.     { "login",    LOGIN },
  70.     { "password",    PASSWD },
  71.     { "passwd",    PASSWD },
  72.     { "account",    ACCOUNT },
  73.     { "machine",    MACH },
  74.     { "macdef",    MACDEF },
  75.     { NULL,        0 }
  76. };
  77.  
  78. int
  79. ruserpass(host, aname, apass, aacct)
  80.     char *host, **aname, **apass, **aacct;
  81. {
  82.     char *hdir, buf[BUFSIZ], *tmp;
  83.     char *myname = 0, *mydomain;
  84.     int t, i, c, usedefault = 0;
  85.     struct stat stb;
  86.  
  87.     hdir = getenv("HOME");
  88.     if (hdir == NULL)
  89.         hdir = ".";
  90.     (void) sprintf(buf, "%s/.netrc", hdir);
  91.     cfile = fopen(buf, "r");
  92.     if (cfile == NULL) {
  93.         if (errno != ENOENT)
  94.             warn("%s", buf);
  95.         return (0);
  96.     }
  97.  
  98.     myname = localhost ();
  99.     if (! myname)
  100.         myname = "";
  101.  
  102.     if ((mydomain = strchr(myname, '.')) == NULL)
  103.         mydomain = "";
  104. next:
  105.     while ((t = token())) switch(t) {
  106.  
  107.     case DEFAULT:
  108.         usedefault = 1;
  109.         /* FALL THROUGH */
  110.  
  111.     case MACH:
  112.         if (!usedefault) {
  113.             if (token() != ID)
  114.                 continue;
  115.             /*
  116.              * Allow match either for user's input host name
  117.              * or official hostname.  Also allow match of 
  118.              * incompletely-specified host in local domain.
  119.              */
  120.             if (strcasecmp(host, tokval) == 0)
  121.                 goto match;
  122.             if (strcasecmp(hostname, tokval) == 0)
  123.                 goto match;
  124.             if ((tmp = strchr(hostname, '.')) != NULL &&
  125.                 strcasecmp(tmp, mydomain) == 0 &&
  126.                 strncasecmp(hostname, tokval, tmp-hostname) == 0 &&
  127.                 tokval[tmp - hostname] == '\0')
  128.                 goto match;
  129.             if ((tmp = strchr(host, '.')) != NULL &&
  130.                 strcasecmp(tmp, mydomain) == 0 &&
  131.                 strncasecmp(host, tokval, tmp - host) == 0 &&
  132.                 tokval[tmp - host] == '\0')
  133.                 goto match;
  134.             continue;
  135.         }
  136.     match:
  137.         while ((t = token()) && t != MACH && t != DEFAULT) switch(t) {
  138.  
  139.         case LOGIN:
  140.             if (token())
  141.                 if (*aname == 0) { 
  142.                     *aname = malloc((unsigned) strlen(tokval) + 1);
  143.                     (void) strcpy(*aname, tokval);
  144.                 } else {
  145.                     if (strcmp(*aname, tokval))
  146.                         goto next;
  147.                 }
  148.             break;
  149.         case PASSWD:
  150.             if ((*aname == NULL || strcmp(*aname, "anonymous")) &&
  151.                 fstat(fileno(cfile), &stb) >= 0 &&
  152.                 (stb.st_mode & 077) != 0) {
  153.     warnx("Error: .netrc file is readable by others.");
  154.     warnx("Remove password or make file unreadable by others.");
  155.                 goto bad;
  156.             }
  157.             if (token() && *apass == 0) {
  158.                 *apass = malloc((unsigned) strlen(tokval) + 1);
  159.                 (void) strcpy(*apass, tokval);
  160.             }
  161.             break;
  162.         case ACCOUNT:
  163.             if (fstat(fileno(cfile), &stb) >= 0
  164.                 && (stb.st_mode & 077) != 0) {
  165.     warnx("Error: .netrc file is readable by others.");
  166.     warnx("Remove account or make file unreadable by others.");
  167.                 goto bad;
  168.             }
  169.             if (token() && *aacct == 0) {
  170.                 *aacct = malloc((unsigned) strlen(tokval) + 1);
  171.                 (void) strcpy(*aacct, tokval);
  172.             }
  173.             break;
  174.         case MACDEF:
  175.             if (proxy) 
  176.                 goto done;
  177.  
  178.             while ((c=getc(cfile)) != EOF && c == ' ' || c == '\t');
  179.             if (c == EOF || c == '\n') {
  180.                 printf("Missing macdef name argument.\n");
  181.                 goto bad;
  182.             }
  183.             if (macnum == 16) {
  184.                 printf("Limit of 16 macros have already been defined\n");
  185.                 goto bad;
  186.             }
  187.             tmp = macros[macnum].mac_name;
  188.             *tmp++ = c;
  189.             for (i=0; i < 8 && (c=getc(cfile)) != EOF &&
  190.                 !isspace(c); ++i) {
  191.                 *tmp++ = c;
  192.             }
  193.             if (c == EOF) {
  194.                 printf("Macro definition missing null line terminator.\n");
  195.                 goto bad;
  196.             }
  197.             *tmp = '\0';
  198.             if (c != '\n') {
  199.                 while ((c=getc(cfile)) != EOF && c != '\n');
  200.             }
  201.             if (c == EOF) {
  202.                 printf("Macro definition missing null line terminator.\n");
  203.                 goto bad;
  204.             }
  205.             if (macnum == 0) {
  206.                 macros[macnum].mac_start = macbuf;
  207.             }
  208.             else {
  209.                 macros[macnum].mac_start = macros[macnum-1].mac_end + 1;
  210.             }
  211.             tmp = macros[macnum].mac_start;
  212.             while (tmp != macbuf + 4096) {
  213.                 if ((c=getc(cfile)) == EOF) {
  214.                 printf("Macro definition missing null line terminator.\n");
  215.                     goto bad;
  216.                 }
  217.                 *tmp = c;
  218.                 if (*tmp == '\n') {
  219.                     if (*(tmp-1) == '\0') {
  220.                        macros[macnum++].mac_end = tmp - 1;
  221.                        break;
  222.                     }
  223.                     *tmp = '\0';
  224.                 }
  225.                 tmp++;
  226.             }
  227.             if (tmp == macbuf + 4096) {
  228.                 printf("4K macro buffer exceeded\n");
  229.                 goto bad;
  230.             }
  231.             break;
  232.         default:
  233.             warnx("Unknown .netrc keyword %s", tokval);
  234.             break;
  235.         }
  236.         goto done;
  237.     }
  238. done:
  239.     (void) fclose(cfile);
  240.     if (myname && *myname)
  241.         free (myname);
  242.     return (0);
  243. bad:
  244.     (void) fclose(cfile);
  245.     if (myname && *myname)
  246.         free (myname);
  247.     return (-1);
  248. }
  249.  
  250. static int
  251. token()
  252. {
  253.     char *cp;
  254.     int c;
  255.     struct toktab *t;
  256.  
  257.     if (feof(cfile) || ferror(cfile))
  258.         return (0);
  259.     while ((c = getc(cfile)) != EOF &&
  260.         (c == '\n' || c == '\t' || c == ' ' || c == ','))
  261.         continue;
  262.     if (c == EOF)
  263.         return (0);
  264.     cp = tokval;
  265.     if (c == '"') {
  266.         while ((c = getc(cfile)) != EOF && c != '"') {
  267.             if (c == '\\')
  268.                 c = getc(cfile);
  269.             *cp++ = c;
  270.         }
  271.     } else {
  272.         *cp++ = c;
  273.         while ((c = getc(cfile)) != EOF
  274.             && c != '\n' && c != '\t' && c != ' ' && c != ',') {
  275.             if (c == '\\')
  276.                 c = getc(cfile);
  277.             *cp++ = c;
  278.         }
  279.     }
  280.     *cp = 0;
  281.     if (tokval[0] == 0)
  282.         return (0);
  283.     for (t = toktab; t->tokstr; t++)
  284.         if (!strcmp(t->tokstr, tokval))
  285.             return (t->tval);
  286.     return (ID);
  287. }
  288.